﻿using UnityEngine;
using System.Collections;
using UnityEngine.Networking;
using UnityEngine.Networking.Match;
using UnityEngine.Networking.NetworkSystem;
using System.Collections.Generic;

namespace demo2
{
    public class Manager : NetworkManager
    {
        const short CustomClientChangedLevelMsgId = 7001;
        // Use this for initialization
        void Start()
        {
            SpawnManager _spawnManager = SpawnManager.Instance();


			// server:当客户端切关结束, 发送给server特定消息后, server重新生成本关的, 可销毁型网络物体
            NetworkServer.RegisterHandler(CustomClientChangedLevelMsgId, ServerOnCustomClientSceneChanged);
        }

        // Update is called once per frame
        void Update()
        {

        }

        #region process
        // 需要处理客户端可能比服务器切得快的情况
        /// <summary>
        /// Called on server, handle level changed finished message, create network objects
        /// trigged by enter Gamestate_playScene state
        /// </summary>
        /// <param name="netMsg"></param>
        List<NetworkMessage> pendingMessages = new List<NetworkMessage>();
        void ServerOnCustomClientSceneChanged(NetworkMessage netMsg)
        {
            Debug.LogWarning("ServerOnCustomClientSceneChanged");
           /* string sceneName = UnityEngine.SceneManagement.SceneManager.GetActiveScene().name;
            if (sceneName != NetworkManager.networkSceneName) // 客户端比server先切关完成
            {
                pendingMessages.Add(netMsg);
            }
            else
            {
                // 当其他客户端在server之后切关完成
                var connGameplayer = GamePlayer.GetPlayerByAdress(netMsg.conn.address);

                var beginMessage = netMsg.ReadMessage<StringMessage>();
                //  Debug.LogWarning("received ServerOnCustomClientSceneChanged " + netMsg.conn.address + " while my id is :" + myConnecionAdress);
                bool isServerOnly = connGameplayer != null && connGameplayer.playerData.isServerModeClient;// ConfigManager.isServeronly && (myConnecionAdress == netMsg.conn.address || netMsg.conn.address.Contains("local"));
                Debug.LogWarning("SetClientReady");
                NetworkServer.SetClientReady(netMsg.conn);
                Debug.LogWarning("GenerateSelfNetworkObjects");
                SceneConstructerCollection.GetConstructer().GenerateSelfNetworkObjects(netMsg.conn, connGameplayer.ToGamePlayerData());


                // 当服务器切关完成, 触发host的切关完成事件时
                //  if (myConnecionAdress == netMsg.conn.address || netMsg.conn.address.Contains("local"))
                if (connGameplayer.playerData.isServerOrHost)
                {
                    SceneConstructerCollection.GetConstructer().GenerateSharedNetworkObjects();

                    foreach (var pendingMsg in pendingMessages)
                    {

                        var beginMessagePending = pendingMsg.ReadMessage<StringMessage>();
                        var pendingConnGameplayer = GamePlayer.GetPlayerByAdress(pendingMsg.conn.address);
                        //  Debug.LogWarning("pendingMsg received ServerOnCustomClientSceneChanged " + pendingMsg.conn.address + " while my id is :" + myConnecionAdress);
                        bool isServerOnlyPending = pendingConnGameplayer != null && pendingConnGameplayer.playerData.isServerModeClient;// ConfigManager.isServeronly && (myConnecionAdress == pendingMsg.conn.address || pendingMsg.conn.address.Contains("local"));
                        Debug.LogWarning("pendingMsg SetClientReady");
                        NetworkServer.SetClientReady(pendingMsg.conn);
                        Debug.LogWarning("pendingMsg GenerateSelfNetworkObjects");
                        SceneConstructerCollection.GetConstructer().GenerateSelfNetworkObjects(pendingMsg.conn, pendingConnGameplayer.ToGamePlayerData());
                    }
                    pendingMessages.Clear();

                }
            }*/
        }
        class AddPlayerExMessage : MessageBase
        {
            public int chairPosId; 
            public bool isMaster;
            public string adress;
            public override void Deserialize(NetworkReader reader)
            {
                chairPosId = reader.ReadInt32();
                isMaster = reader.ReadBoolean();
                adress = reader.ReadString();
            }

            public override void Serialize(NetworkWriter writer)
            {
                writer.Write(chairPosId);
                writer.Write(isMaster);
                writer.Write(adress);
            }

        }






        #endregion

		#region 在服务器（Server）和伺服器（Host）上调用的函数

        //客户端连接时被调用
        public override void OnServerConnect(NetworkConnection conn)
        {
            Debug.LogError("OnServerConnect");

        }
        // 客户端断开连接是被调用 
        public override void OnServerDisconnect(NetworkConnection conn)
        {
            Debug.LogError("OnServerDisconnect");
        }
        // 客户端准备好的时候调用  
        public override void OnServerReady(NetworkConnection conn)
        {
            Debug.LogError("OnServerReady");
            //NetworkServer.SetClientReady(conn); ClientScene.ready  ClientScene.Ready(conn);
        }
        // 当有一个新的客户端加入的时候调用   
        public override void OnServerAddPlayer(NetworkConnection conn, short playerControllerId)
        {
            Debug.LogError("OnServerAddPlayer 1");
        }
        public override void OnServerAddPlayer(NetworkConnection conn, short playerControllerId, NetworkReader extraMessageReader)
        {
            Debug.LogError("OnServerAddPlayer 2");
            
			Debug.Log("Do OnServerAddPlayer " + conn);
			AddPlayerExMessage exMsg = new AddPlayerExMessage();
			exMsg.Deserialize(extraMessageReader);
			//派生一个玩家，注意与普通物体派生不一样
			SpawnManager.Instance().SpawnPlayer(conn, playerControllerId);
			Debug.LogFormat("finish addp player: chairId:{0}  isMaster:{1}, adress:{2}", exMsg.chairPosId, exMsg.isMaster, exMsg.adress);


			//创建一个客户端授权的物体
            GameObject cubeAobject =  SpawnManager.Instance().SpawWithClientAuthority("CubeA", conn);
			//创建一个普通物体
			GameObject sphereAobject = SpawnManager.Instance().Spawn("SphereA",new Vector3(2,3,2),Quaternion.Euler(new Vector3(20,20,20)));


        }
        // 一个客户端的玩家物体被移除的时候调用  
        public override void OnServerRemovePlayer(NetworkConnection conn, PlayerController player)
        {
            Debug.LogError("OnServerRemovePlayer");
        }
        // 有网络错误发生的时候调用  
        public override void OnServerError(NetworkConnection conn, int errorCode)
        {
            Debug.LogError("OnServerError");
        }

        #endregion

        #region 在客户端上被调用函数
        // 客户端连接到服务器的时候调用 
        public override void OnClientConnect(NetworkConnection conn)
        {
            Debug.LogError("OnClientConnect");
            //client: 当链接到server后, 添加player
            
			Debug.Log("[All] AddPlayerWhenGotConnectInClient");

			AddPlayerExMessage exMsg = new AddPlayerExMessage();
			exMsg.chairPosId = 1;
			exMsg.isMaster = false;
			exMsg.adress = "xxx_yyy_zzz";

			ClientScene.AddPlayer(conn, 0, exMsg);


        }
        // 连接断开 客户端调用
        public override void OnClientDisconnect(NetworkConnection conn)
        {
            base.OnClientDisconnect(conn);
            Debug.LogError("OnClientDisconnect");
        }
        // 被服务器告知还没准备好的时候调用
        public override void OnClientNotReady(NetworkConnection conn)
        {
            Debug.LogError("OnClientNotReady");
        }
        public override void OnClientSceneChanged(NetworkConnection conn)
        {
            Debug.LogError("OnClientSceneChanged");
			// client: 切关时,生成clietn local本地物体. 注意: 刚进来时不会触发
			///Debug.Log("OnCLientSceneChanged");
			//*_*if (UnityEngine.SceneManagement.SceneManager.GetActiveScene().name != DEF.OfficeLineSceneName)
			{
				//if (!ClientScene.ready)
				//    ClientScene.Ready(myConn);
				if (!ClientScene.ready)
				{
					ClientScene.Ready(conn);
					Debug.Log("  ClientScene.Ready(conn) ");
				}
				//*_*SceneConstructerCollection.GetConstructer().GenerateSceneLocalObj();

				// send level changed finished message to server , then server wil create network objects
				var msg = new StringMessage(conn.address);
				client.Send(CustomClientChangedLevelMsgId, msg);//客户端发送，服务器接受NetworkServer.RegisterHandler
			}

        }
        // 有网络错误发生的时候调用 
        public override void OnClientError(NetworkConnection conn,int errorCode)
        {
            base.OnClientError(conn, errorCode);
            Debug.LogError("OnClientError");
        }

        #endregion

        #region 在比赛安排中的函数
        // 有比赛被创建的时候调用
        /*public override void OnMatchCreate(CreateMatchResponse matchInfo)
        {
            base.OnMatchCreate(matchInfo);
            Debug.LogError("OnMatchCreate");
        }
        // 接收到比赛列表的时候调用
        public override void OnMatchList(ListMatchResponse matchList)
        {
            base.OnMatchList(matchList);
            Debug.LogError("OnMatchList");
        }
        // 加入比赛的时候调用
        public void OnMatchJoined(JoinMatchResponse matchInfo)
        {
            base.OnMatchJoined(matchInfo);
            Debug.LogError("OnMatchJoined");
        }*/
        #endregion

    }
}
